package com.xhwl.centiotdata.suppliersystem.eesd.en168;

import com.alibaba.fastjson.JSONObject;
import com.xhwl.centiotdata.constant.EesdConstant;
import com.xhwl.centiotdata.utils.StrUtils;
import com.xhwl.common.dto.cent.eesd.EDeviceOnlineDTO;
import com.xhwl.common.dto.cent.eesd.OdsEnvironmentMetricsDTO;
import com.xhwl.common.dto.cent.iotdata.csg.EDeviceRespDTO;
import com.xhwl.common.dto.cent.iotdata.csg.ERealTimeDataRespDTO;
import com.xhwl.common.dto.cent.iotdata.csg.ERoomRespDTO;
import com.xhwl.common.pojo.cent.device.DeviceProjSupplierCategory;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Description: 南方电网-e能管家系统
 * @Copyright: Copyright (c) 2021  ALL RIGHTS RESERVED.
 * @Company: 深圳市兴海物联科技有限公司
 * @Author: gyc
 * @CreateDate: 2021/9/10 17:30
 * @UpdateDate: 2021/9/10 17:30
 * @UpdateRemark: init
 * @Version: 1.0
 */
@Slf4j
@Service
public class CsgHandler {

    /**
     * e能管家系统-获取电房环境数据
     * @return
     */
    public List<OdsEnvironmentMetricsDTO> getERoomEnv(DeviceProjSupplierCategory config) throws Exception {
        List<OdsEnvironmentMetricsDTO> list = new ArrayList<>();
        String authorization = CsgApiUtil.getEToken(config);
        if (StringUtils.isEmpty(authorization)) {
            return list;
        }
        // 项目id
        Integer projectId = config.getProjectId();
        // 产品id
        Integer productId = config.getProductId();
        JSONObject properties = config.getProperties();
        String ip = properties.getString("ip");
        String station = properties.getString("station");
        String customerId = properties.getString("customerId");
        String realTimeData = properties.getString("realTimeData");

        String stationUrl = ip + station;
        Map<String, Object> stationMap = new HashMap<>();
        stationMap.put("customerId", customerId);
        // 1.获取电房数据
        List<ERoomRespDTO> eRoom = CsgApiUtil.getEData(authorization, stationUrl, stationMap, ERoomRespDTO.class);
        String realTimeDataUrl = ip + realTimeData;

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime anHourAgo = LocalDateTime.now().minusHours(1L);

        for (int i = 0; i < eRoom.size(); i++) {
            ERoomRespDTO electricRoomRespDTO = eRoom.get(i);
            String id = electricRoomRespDTO.getId();
            String name = electricRoomRespDTO.getName();

            OdsEnvironmentMetricsDTO odsEnvironmentMetricsDTO = new OdsEnvironmentMetricsDTO();
            odsEnvironmentMetricsDTO.setProductId(productId);
            odsEnvironmentMetricsDTO.setDeviceId(id);
            odsEnvironmentMetricsDTO.setName(name);
            odsEnvironmentMetricsDTO.setProjectId(projectId);


            Map<String, Object> realTimeDataMap = new HashMap<>();
            realTimeDataMap.put("customerId", customerId);
            realTimeDataMap.put("stationId", id);

            List<ERealTimeDataRespDTO> eData = null;
            try {
                eData = CsgApiUtil.getEData(authorization, realTimeDataUrl, realTimeDataMap, ERealTimeDataRespDTO.class);
            } catch (Exception e) {
                log.error("获取实时数据" + i + "错误：" + e.getMessage());
            }
            if (CollectionUtils.isEmpty(eData)) {
                return list;
            }

            for (ERealTimeDataRespDTO eRealTimeDataRespDTO : eData) {
                // 2.获取电房的温度、湿度、氧气值
                String value = eRealTimeDataRespDTO.getMeasuringValue();
                // 实际时间
                LocalDateTime realTime = eRealTimeDataRespDTO.getValueDate();
                // 南方电网的-e能管家系统的在离线设备是根据时间是否在当前1h内有没有更新数据
                if (realTime.isBefore(anHourAgo)) {
                    odsEnvironmentMetricsDTO.setDeviceStatus(0);
                } else {
                    odsEnvironmentMetricsDTO.setDeviceStatus(1);
                }

                // 拉取时间
                odsEnvironmentMetricsDTO.setObsTime(now);
                switch (eRealTimeDataRespDTO.getMeasuringNameCode()) {
                    case "SENSE_WD" :
                        if (StrUtils.isNumber(value)) {
                            odsEnvironmentMetricsDTO.setTemp(Double.valueOf(value));
                        } else {
                            odsEnvironmentMetricsDTO.setTemp(EesdConstant.DEFAULT_0D_VALUE);
                        }
                        break;
                    case "SENSE_SD" :
                        if (StrUtils.isNumber(value)) {
                            odsEnvironmentMetricsDTO.setHumidity(Double.valueOf(value));
                        } else {
                            odsEnvironmentMetricsDTO.setHumidity(EesdConstant.DEFAULT_0D_VALUE);
                        }
                        break;
                    case "DFHJ_YQ" :
                        if (StrUtils.isNumber(value)) {
                            odsEnvironmentMetricsDTO.setO2(Double.valueOf(value));
                        } else {
                            odsEnvironmentMetricsDTO.setO2(EesdConstant.DEFAULT_0D_VALUE);
                        }
                        break;
                    default :
                }
            }
            list.add(odsEnvironmentMetricsDTO);
        }
        return list;
    }



    /**
     * e能管家系统-获取电房的设备在离线数据
     * @param config
     * @return
     */
    public List<EDeviceOnlineDTO> getERoomDeviceOnline(DeviceProjSupplierCategory config) throws Exception {
        List<EDeviceOnlineDTO> list = new ArrayList<>();
        String authorization = CsgApiUtil.getEToken(config);
        if (StringUtils.isEmpty(authorization)) {
            return list;
        }

        LocalDateTime anHourAgo = LocalDateTime.now().minusHours(1L);
        Integer projectId = config.getProjectId();

        JSONObject properties = config.getProperties();
        String ip = properties.getString("ip");
        String station = properties.getString("station");
        String customerId = properties.getString("customerId");
        String realTimeData = properties.getString("realTimeData");
        String device = properties.getString("device");
        // 电房设备类型
        List<Integer> typeList = (List<Integer>) properties.get("typeList");

        String stationUrl = ip + station;
        Map<String, Object> stationMap = new HashMap<>();
        stationMap.put("customerId", customerId);
        // 1.获取电房数据
        List<ERoomRespDTO> eRoomData = CsgApiUtil.getEData(authorization, stationUrl, stationMap, ERoomRespDTO.class);

        // 2.电房-设备数据
        String deviceUrl = ip + device;
        Map<String, Object> deviceMap = new HashMap<>();
        deviceMap.put("customerId", customerId);
        List<EDeviceRespDTO> eDeviceData = CsgApiUtil.getEData(authorization, deviceUrl, deviceMap, EDeviceRespDTO.class);


        for (ERoomRespDTO eRoom : eRoomData) {
            // 电房id 电房id与设备id关联
            String id = eRoom.getId();
            // 电房名称
            String name = eRoom.getName();

            // 3.分类统计-每个电房下设备实时数据
            String realTimeDataUrl = ip + realTimeData;
            Map<String, Object> realTimeDataMap = new HashMap<>(16);
            realTimeDataMap.put("customerId", customerId);
            realTimeDataMap.put("stationId", id);
            List<ERealTimeDataRespDTO> eRealTimeData = CsgApiUtil.getEData(authorization, realTimeDataUrl, realTimeDataMap, ERealTimeDataRespDTO.class);
            // 每个电房下设备实时数据根据设备id去重
            List<ERealTimeDataRespDTO> dList = eRealTimeData.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(ERealTimeDataRespDTO::getDeviceId))), ArrayList::new));

            for (Integer type : typeList) {
                // 根据设备类型分组
                List<EDeviceRespDTO> eList = eDeviceData.stream().filter(e -> Objects.nonNull(e.getDeviceType()) && e.getDeviceType().equals(type)).collect(Collectors.toList());

                Integer onlineNum = 0;
                // 对比
                for (EDeviceRespDTO eDeviceRespDTO : eList) {
                    for (ERealTimeDataRespDTO eRealTimeDataRespDTO : dList) {
                        // 判断设备数据的设备id与设备实时数据中的设备id是否相等
                        if (eDeviceRespDTO.getId().equals(eRealTimeDataRespDTO.getDeviceId())) {
                            // 取出设备实时数据的时间
                            LocalDateTime valueDate = eRealTimeDataRespDTO.getValueDate();
                            // 1小时没有更新 离线了
                            if (valueDate.isBefore(anHourAgo)) {
                                onlineNum = onlineNum++;
                            }
                        }
                    }

                }
                EDeviceOnlineDTO eDeviceOnlineVO = new EDeviceOnlineDTO();
                eDeviceOnlineVO.setDeviceId(id);
                eDeviceOnlineVO.setName(name);
                eDeviceOnlineVO.setType(type);
                eDeviceOnlineVO.setTotal(eList.size());
                eDeviceOnlineVO.setOnline(onlineNum);
                eDeviceOnlineVO.setOffline(eList.size() - onlineNum);
                eDeviceOnlineVO.setProjectId(projectId);
                list.add(eDeviceOnlineVO);
            }
        }
        return list;
    }


}
